/**
 * @author xxxx.xx
 * @description 封装axios
 */
import axios from 'axios'

// 引入Store实例，然后获取token数据
import Store from '../store'

// (method) AxiosStatic.create(config?: AxiosRequestConfig): AxiosInstance
// create方法可以创建一个Axios实例，在创建实例的时候，可以传递一些参数进去，那么实例中就会有这些参数
// 实现通用配置和业务配置分离(解耦)
const Axios = axios.create({
    baseURL: '/apis',
    timeout: 5000
})

// 请求前的一个拦截 -- 如果用户访问的接口需要token才能访问，那么一定要有token才行
// use(onFulfilled?: (value: AxiosRequestConfig) => AxiosRequestConfig | Promise)
// 拦截钩子函数 -- 函数会有一个AxiosRequestConfig形参传递进来；(=> AxiosRequestConfig | Promise) 一定要返回一个AxiosRequestConfig对象，如果失败可以返回一个Promise的失败
Axios.interceptors.request.use(function(config) {

    // config.headers.token = 'fdslfjdsfldsjfslfds' 测试代码

    // 通过url来进行业务拦截，如果是符合条件则不拦截，否则执行拦截
    // if (config.url === '/user/validate/code' || config.url === '/user/app/login')
    let paths = ['/user/validate/code', '/user/app/login']

    if (paths.includes(config.url)) {
        return config
    } else {
        // 获取vuex中的token数据
        const token = Store.getters['common/token']

        // 如果没有token直接返回错误信息
        if (!!token) {
            config.headers.token = token
            return config
        } else {
            return Promise.reject({code: 400, message: '你已被拦截处理，不具备访问这个接口权限'})
        }
    }

    // 测试代码
    // // 返回成功
    // return config
    // // 返回一个失败信息
    // return Promise.reject({code: 400, message: '你已被拦截处理'})
})

// function Ajax(url, method, data, params) { 参数过多，而且除了url不是每一个参数都是必传
function Ajax(req) {
    // (method) Axios.request(config: AxiosRequestConfig<D>): Promise
    // interface AxiosRequestConfig<D = any> {
    //     url?: string;
    //     method?: Method;
    //     baseURL?: string;
    //     transformRequest?: AxiosRequestTransformer | AxiosRequestTransformer[];
    //     transformResponse?: AxiosResponseTransformer | AxiosResponseTransformer[];
    //     headers?: AxiosRequestHeaders;
    //     params?: any;
    //     paramsSerializer?: (params: any) => string;
    //     data?: D;
    //     timeout?: number;
    //     timeoutErrorMessage?: string;
    //     withCredentials?: boolean;
    //     adapter?: AxiosAdapter;
    //     auth?: AxiosBasicCredentials;
    //     responseType?: ResponseType;
    //     xsrfCookieName?: string;
    //     xsrfHeaderName?: string;
    //     onUploadProgress?: (progressEvent: any) => void;
    //     onDownloadProgress?: (progressEvent: any) => void;
    //     maxContentLength?: number;
    //     validateStatus?: ((status: number) => boolean) | null;
    //     maxBodyLength?: number;
    //     maxRedirects?: number;
    //     socketPath?: string | null;
    //     httpAgent?: any;
    //     httpsAgent?: any;
    //     proxy?: AxiosProxyConfig | false;
    //     cancelToken?: CancelToken;
    //     decompress?: boolean;
    //     transitional?: TransitionalOptions;
    //     signal?: AbortSignal;
    //     insecureHTTPParser?: boolean;
    // }
    // 因为要使用async + await => 不能接受catch回调
    // axios.request({
    //     url: '/user/validate/code',
    //     method: 'POST',
    //     baseURL: '/apis',
    //     data: {phone},
    //     params: {phone},
    //     timeout: 5000
    // })
    // 重新返回一个只有resolve的Promise，async+await可以处理所有业务
    return new Promise(resolve => {
        // axios.request({
        // 因为Axios里边有集成通用配置，所以用它发起请求，这些通用会生效
        Axios.request({
            url: req.url,
            method: req.method || 'POST',
            // baseURL: '/apis',
            // 在请求体传递参数 -- POST请求
            data: req.data || {},
            // 在请求地址上传递参数，就需要使用这个属性 -- GET请求
            params: req.params || {},
            // timeout: 5000
        }).then(({data}) => {
            resolve(data)
        }).catch(e => {
            console.log(e)
            resolve({code: 888, message: '异步请求失败'})
        })
    })
}

export default Ajax